/*
 * mixedflowslicerenderer2d.h
 *
 *  Created on: 30/07/2012
 *      Author: cvan680
 */

#ifndef VRN_MIXEDFLOWSLICERENDERER2D_H_
#define VRN_MIXEDFLOWSLICERENDERER2D_H_


#include "tgt/vector.h"
#include "voreen/core/processors/renderprocessor.h"
#include "modules/flowreen/processors/flowreenprocessor.h"

#include <typeinfo>

/**
 * TODO remove anything from original FlowSliceRenderer2D that we don't need.
 * - Do we want this module to do all techniques that FlowSliceRenderer offers?
 * - Or do we only want to try LIC?
 */

namespace voreen {

template<typename T>
class MixedFlowSliceRenderer2D : public RenderProcessor, public FlowreenProcessor {

public:
    MixedFlowSliceRenderer2D();
    virtual ~MixedFlowSliceRenderer2D();

    virtual Processor* create() const { return new MixedFlowSliceRenderer2D(); }
    virtual std::string getCategory() const { return "Multi-field visualization"; }
    virtual std::string getClassName() const { return "MixedFlowSliceRenderer2D"; }
    virtual CodeState getCodeState() const  { return CODE_STATE_EXPERIMENTAL; }

    virtual void process();
    virtual void initialize() throw (tgt::Exception);
    virtual void deinitialize() throw (tgt::Exception);

protected:
    enum SliceAlignment {
        PLANE_XY = 2,   /** view from the volume's front to back (negative z-axis) */
        PLANE_XZ = 1,   /** view from the volume's bottom to top (negative y-axis) */
        PLANE_ZY = 0    /** view from the volume's right to left (negative x-axis) */
    };

    virtual void setDescriptions() {
        setDescription("Renders two screen aligned 2D flow images from slices in two "
        			   "3D vector fields.");
    }

private:


    /**
     * Renders a 2D texture containing flow images derived from the input flow volume
     * and by using the given technique. According to the technique, this methods
     * deligates to the other rendering methods.
     *
     * @param   flow    The flow data from which the texture shall be generated.
     * @param   sliceNo The number of the slice for which the texture shall be
     *                  generated.
     * @param   textureScaling  Determines the magnification of the output texture
     *                          according to the input flow texture respectively to
     *                          size of the slice taken from it. A value of 2 for
     *                          instance will generate a texture of double input size.
     *                          This parameter may not be negative.
     * @param   thresholds  Lower and upper threshold for the flow magnitudes which
     *                      shall be rendered. The thresholds are absolute values
     *                      of the magnitudes from the input flow texture. Magnitudes
     *                      not within the range of the thresholds will be dropped
     *                      during texture generation.
     */
    tgt::Texture* renderFlowTexture(const Flow3D& flow1, const Flow3D& flow2, const size_t sliceNo,
        const int textureScaling, const tgt::vec2& thresholds);

    /**
     * Performs the generation of an image of the specified slice through
     * the flow volume by using FastLIC (line integral convolution).
     * The returned pointer is stored in a tgt::Texture and deleted
     * by that dtor.
     */
    static T* fastLIC(const Flow2D& flow1, const Flow2D& flow2, const SimpleTexture<float>& inputTexture,
        const size_t textureScaling, const size_t sampling, const int maxKernelSize,
        const tgt::vec2& threshold = tgt::vec2(0.0f), const bool useAdaptiveKernelSize = false);

    // Helper variables
    tgt::ivec3 permutation_;        /** permutation of the components of the flow according to selected slice alignment */

    // Properties
    IntProperty pixelSamplingProp_;
    BoolProperty useAdaptiveKernelSizeProp_;
    IntProperty kernelSizeProp_;

    // Ports
    VolumePort inport_volume1_;
    VolumePort inport_volume2_;
    RenderPort outport_img;
};


#endif /* VRN_MIXEDFLOWSLICERENDERER2D_H_ */
